package com.xhh.nphm.web.controller.system;

import com.xhh.nphm.common.core.controller.BaseController;
import com.xhh.nphm.common.core.domain.AjaxResult;
import com.xhh.nphm.common.core.domain.entity.SysUser;
import com.xhh.nphm.common.core.page.TableDataInfo;
import com.xhh.nphm.common.utils.DateUtils;
import com.xhh.nphm.common.utils.ShiroUtils;
import com.xhh.nphm.system.domain.InfoRecord;
import com.xhh.nphm.system.domain.SensitiveInfo;
import com.xhh.nphm.system.domain.SensitiveInfoField;
import com.xhh.nphm.system.service.ISensitiveInfoService;
import com.xhh.nphm.system.service.InfoRecordService;
import com.xhh.nphm.system.service.SensitiveInfoFieldService;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * 敏感信息控制层
 * @author zz
 */
@RestController
@RequestMapping("system/sensitive")
public class SensitiveInfoController extends BaseController {
    private final String prefix = "system/sensitive";
    /**
     * 敏感信息业务层对象
     */
    @Autowired
    private ISensitiveInfoService sensitiveInfoService;
    /**
     * 敏感信息日志业务层对象
     */
    @Autowired
    private InfoRecordService infoRecordService;
    /**
     * 敏感信息属性业务层对象
     */
    @Autowired
    private SensitiveInfoFieldService infoFieldService;


    /**
     * 进入敏感信息属性管理页面
     * @return 视图对象
     */
    @GetMapping("/infoField/list")
    public ModelAndView sensitiveInfoField(){
        return new ModelAndView(prefix + "/infoField/list");
    }

    /**
     * 加载敏感信息属性管理页面列表数据
     * @param infoField 查询条件
     * @return 列表数据
     */
    @PostMapping("/infoField/listJson")
    public TableDataInfo sensitiveInfoFieldJson(SensitiveInfoField infoField){
        startPage();
        List<SensitiveInfoField> list = infoFieldService.sensitiveInfoFieldJson(infoField);
        return getDataTable(list);
    }

    /**
     * 进入新增或修改敏感信息属性页面
     * @param id 对象编号
     * @param map 模型对象
     * @return 视图对象
     */
    @GetMapping(value = {"/infoField/add","/infoField/edit/{id}"})
    public ModelAndView saveOrUpdate(@PathVariable(required = false) Integer id,ModelMap map){
        map.put("infoField",infoFieldService.getById(id));
        return new ModelAndView(prefix + "/infoField/saveOrUpdate");
    }

    /**
     * 新增或编辑敏感信息属性
     * @param infoField 敏感信息属性对象
     * @return 操作结果
     */
    @PostMapping("/infoField/saveOrUpdate")
    public AjaxResult saveOrUpdate(@RequestBody SensitiveInfoField infoField){
        return toAjax(infoFieldService.saveOrUpdate(infoField));
    }

    /**
     * 批量删除敏感信息属性
     * @param ids 敏感信息属性id
     * @return 操作结果
     */
    @PostMapping("/infoField/remove")
    public AjaxResult remove(String... ids){
        return toAjax(infoFieldService.removeByIds(Arrays.asList(ids)));
    }


    /**
     * 进入到敏感信息页面
     * @param id 敏感信息id
     * @param mav 视图对象
     * @return 视图对象
     */
    @GetMapping("/page/{id}")
    public ModelAndView toPage(@PathVariable("id")Integer id, ModelAndView mav){
        //敏感信息实体
        SensitiveInfo sensitivity = new SensitiveInfo();
        //校验是否存在敏感信息Id
        if(id != 0){
            //存在就查询敏感信息
            sensitivity = sensitiveInfoService.findOneById(id);
        }
        //添加敏感信息实体到页面中
        mav.addObject("sensitivity",sensitivity);
        //设置页面路径
        mav.setViewName(prefix + "/add");
        return mav;
    }

    /**
     * 进入到敏感信息页面
     * @param id 敏感信息id
     * @param mav 视图对象
     * @return 视图对象
     */
    @GetMapping("/read/{id}")
    public ModelAndView toRead(@PathVariable("id")Integer id, ModelAndView mav){
        //敏感信息实体
        SensitiveInfo sensitivity = new SensitiveInfo();
        //校验是否存在敏感信息Id
        if(id != 0){
            //存在就查询敏感信息
            sensitivity = sensitiveInfoService.findOneById(id);
        }
        //添加敏感信息实体到页面中
        mav.addObject("sensitivity",sensitivity);
        //设置页面路径
        mav.setViewName(prefix + "/read");
        return mav;
    }

    /**
     * 新增或修改敏感信息
     * @return 响应数据
     */
    @PostMapping("/saveOrUpdate")
    public AjaxResult saveOrUpdate(@RequestBody SensitiveInfo sensitiveInfo) throws IllegalAccessException {
        //保存响应结果
        AjaxResult result = AjaxResult.warn("前端传参对象为空");
        //封装敏感信息日志对象信息
        SysUser user = ShiroUtils.getSysUser();
        InfoRecord info = new InfoRecord();
        info.setDeptId(user.getDeptId());
        info.setVisitTime(DateUtils.getNowDate());
        info.setUserNo(user.getUserNo());
        info.setUserName(user.getUserName());
        //校验前端传参不为空
        if (!Objects.isNull(sensitiveInfo)) {
            assert false;
            //校验对象是否有主键Id ? 修改 ：新增
            if(Objects.isNull(sensitiveInfo.getId())){
                sensitiveInfo.setCreateDate(DateUtils.getNowDate());
                //执行新增敏感信息业务方法
                int res = sensitiveInfoService.insert(sensitiveInfo);
                //设置敏感信息日志对象备注
                info.setRemark("新增敏感信息");
                //设置敏感信息日志的被访问敏感信息id
                info.setVisitId(Long.valueOf(sensitiveInfo.getId()));
                //响应结果 （生成的敏感信息主键Id）
                result = AjaxResult.success(res);
            }else {
                //执行修改敏感信息业务方法
                boolean updateFlag = sensitiveInfoService.updateInfoDetail(sensitiveInfo);
                //设置敏感信息日志对象备注
                info.setRemark("修改敏感信息");
                //设置敏感信息日志的被访问敏感信息id
                info.setVisitId(Long.valueOf(sensitiveInfo.getId()));
                //响应结果 (修改是否成功)
                result = updateFlag ? AjaxResult.success(sensitiveInfo.getId()) : AjaxResult.error("修改失败");
            }
        }
        //新增敏感信息操作日志
        infoRecordService.save(info);
        return result;
    }

    /**
     * 校验对象的属性是否为空
     * @param object 对象
     * @param excludeFields 不验证的属性
     * @return  校验结果 true=任一不为空，false=都为空
     */
    public boolean validateField(Object object, List<String> excludeFields) throws IllegalAccessException {
        //保存校验结果
        boolean flag = false;
        //获取对象的所有字段
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            //设置属性可访问
            field.setAccessible(true);
            //获取属性名
            String fieldName = field.getName();
            //判断该属性是否被排除校验
            if (!excludeFields.contains(fieldName)) {
                //判断属性是否为空
                if(field.get(object) != null && field.get(object) != ""){
                    flag = true;
                }
            }
        }
        return flag;
    }
}
